Replace use of Expat with QXmlStreamReaader in navicache.cc.
authorrobertlipe <robertlipe@f51c46e8-681c-474f-0cfe-069cfd0219fb>
Fri, 16 Aug 2013 05:30:55 +0000 (05:30 +0000)
committerrobertlipe <robertlipe@f51c46e8-681c-474f-0cfe-069cfd0219fb>
Fri, 16 Aug 2013 05:30:55 +0000 (05:30 +0000)
gpsbabel/navicache.cc

index f9d25cea572f7235034de2f1e2913dfd8545c702..cc4a6ce8a40d9e9d5e3f3a0c5111eeb308abfd0e 100644 (file)
@@ -1,5 +1,5 @@
 /*
-    Copyright (C) 2003 Robert Lipe, robertlipe@usa.net
+    Copyright (C) 2003-2013 Robert Lipe, robertlipe@gpsbabel.org
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
  */
 #include "defs.h"
 #include "cet_util.h"
-#if HAVE_LIBEXPAT
-#include <expat.h>
-static XML_Parser psr;
-#endif
-
-static waypoint* wpt_tmp;
-
-static gbfile* fin, *fout;
+#include <QtCore/QXmlStreamReader>
+#include "src/core/file.h"
 
 static char* noretired = NULL;
+static const char* read_fname = NULL;
 
 static
 arglist_t nav_args[] = {
@@ -39,22 +34,8 @@ arglist_t nav_args[] = {
 };
 
 #define MYNAME "navicache"
-#define MY_CBUF 4096
 #define NC_URL "http://www.navicache.com/cgi-bin/db/displaycache2.pl?CacheID="
 
-#if ! HAVE_LIBEXPAT
-static void
-nav_rd_init(const char* fname)
-{
-  fatal(MYNAME ": This build excluded GPX support because expat was not installed.\n");
-}
-
-static void
-nav_read(void)
-{
-}
-#else
-
 static struct
     nc_type_mapping {
   geocache_type type;
@@ -81,13 +62,13 @@ static struct
 
 static
 geocache_type
-nc_mktype(const char* t)
+nc_mktype(const QString& t)
 {
   int i;
   int sz = sizeof(nc_type_map) / sizeof(nc_type_map[0]);
 
   for (i = 0; i < sz; i++) {
-    if (0 == case_ignore_strcmp(t, nc_type_map[i].name)) {
+    if (0 == t.compare(nc_type_map[i].name, Qt::CaseInsensitive)) {
       return nc_type_map[i].type;
     }
   }
@@ -96,13 +77,13 @@ nc_mktype(const char* t)
 
 static
 geocache_container
-nc_mkcont(const char* t)
+nc_mkcont(const QString& t)
 {
   int i;
   int sz = sizeof(nc_container_map) / sizeof(nc_container_map[0]);
 
   for (i = 0; i < sz; i++) {
-    if (0 == case_ignore_strcmp(t, nc_container_map[i].name)) {
+    if (0 == t.compare(nc_container_map[i].name, Qt::CaseInsensitive)) {
       return nc_container_map[i].type;
     }
   }
@@ -110,152 +91,122 @@ nc_mkcont(const char* t)
 }
 
 static void
-nav_start(void* data, const XML_Char* xml_el, const XML_Char** xml_attr)
+nav_rd_init(const char* fname)
 {
-  const char* el;
-  const char** attr;
-
-  el = xml_convert_to_char_string(xml_el);
-  attr = xml_convert_attrs_to_char_string(xml_attr);
-  if (0 == strcmp(el, "CacheDetails")) {
-    const char** ap;
-    geocache_data* gc_data;
-    wpt_tmp = waypt_new();
-    gc_data = waypt_alloc_gc_data(wpt_tmp);
-
-    for (ap = attr; *ap; ap+=2) {
-      if (0 == strcmp(ap[0], "cache_id")) {
-        int id;
-
-        id = atoi(ap[1]);
-        xasprintf(&wpt_tmp->shortname, "N%05X", id);
-        UrlLink l(QString(NC_URL) + QString::number(id));
-        wpt_tmp->AddUrlLink(l);
-      } else if (0 == strcmp(ap[0], "name")) {
-        wpt_tmp->description = xstrdup(ap[1]);
-      } else if (0 == strcmp(ap[0], "user_name")) {
-        gc_data->placer = ap[1];
-      } else if (0 == strcmp(ap[0], "latitude")) {
-        sscanf(ap[1], "%lf",
-               &wpt_tmp->latitude);
-      } else if (0 == strcmp(ap[0], "longitude")) {
-        sscanf(ap[1], "%lf",
-               &wpt_tmp->longitude);
-      } else if (0 == strcmp(ap[0], "longitude")) {
-        sscanf(ap[1], "%lf",
-               &wpt_tmp->longitude);
-      } else if (0 == strcmp(ap[0], "difficulty")) {
-        float x;
-        sscanf(ap[1], "%f", &x);
-        gc_data->diff = x * 10;
-      } else if (0 == strcmp(ap[0], "terrain")) {
-        float x;
-        sscanf(ap[1], "%f", &x);
-        gc_data->terr = x * 10;
-      } else if (0 == strcmp(ap[0], "cache_type")) {
-        gc_data->type = nc_mktype(ap[1]);
-        if (!strcmp(ap[1], "normal")) {
-          wpt_tmp->icon_descr = "Geocache-regular";
-        } else if (!strcmp(ap[1], "multi-part")) {
-          wpt_tmp->icon_descr = "Geocache-multi";
-        } else if (!strcmp(ap[1], "moving_travelling")) {
-          wpt_tmp->icon_descr = "Geocache-moving";
-        } else {
-          // WARNING: casting away const-ness.
-          xasprintf((char**)&wpt_tmp->icon_descr,
-                    "Geocache-%-.20s", ap[1]);
-        }
-      } else if (0 == strcmp(ap[0], "hidden_date")) {
-        struct tm tm;
-
-        sscanf(ap[1], "%d-%d-%d",
-               &tm.tm_year,
-               &tm.tm_mon,
-               &tm.tm_mday);
-        tm.tm_mon -= 1;
-        tm.tm_year -= 1900;
-        tm.tm_isdst = 0;
-        tm.tm_hour = 0;
-        tm.tm_min = 0;
-        tm.tm_sec = 0;
-        wpt_tmp->SetCreationTime(mktime(&tm));
-      } else if (0 == strcmp(ap[0], "retired")) {
-        if (!strcmp(ap[1], "yes") && noretired) {
-          xfree(wpt_tmp);
-          return;
-        }
-      } else if (0 == strcmp(ap[0], "cache_size")) {
-        gc_data->container = nc_mkcont(ap[1]);
-      }  else if (0 == strcmp(ap[0], "description")) {
-        gc_data->desc_long.is_html = 1;
-        gc_data->desc_long.utfstring = ap[1];
-      } else if (0 == strcmp(ap[0], "comments")) {
-        gc_data->desc_short.is_html = 1;
-        gc_data->desc_short.utfstring = ap[1];
-      }
+  read_fname = fname;
+}
+
+static void
+NaviReadCache(const QXmlStreamReader& reader) {
+  const QXmlStreamAttributes a = reader.attributes();
+  waypoint* wpt_tmp = waypt_new();
+  geocache_data* gc_data;
+  gc_data = waypt_alloc_gc_data(wpt_tmp);
+  if (a.hasAttribute("cache_id")) {
+    int n = a.value("cache_id").toString().toInt();
+    QString fn = QString("N%1").arg(n, 5, 16, QChar('0'));
+    wpt_tmp->shortname = xstrdup(CSTR(fn));
+
+    UrlLink l(QString(NC_URL) + QString::number(n));
+    wpt_tmp->AddUrlLink(l);
+  }
+  if (a.hasAttribute("name")) {
+    wpt_tmp->description = xstrdup(CSTR(a.value("name").toString()));
+  }
+  if (a.hasAttribute("user_name")) {
+    gc_data->placer = a.value("user_name").toString();
+  }
+
+  if (a.hasAttribute("latitude")) {
+    wpt_tmp->latitude = a.value("latitude").toString().toDouble();
+  }
+  if (a.hasAttribute("longitude")) {
+    wpt_tmp->longitude = a.value("longitude").toString().toDouble();
+  }
+
+  if (a.hasAttribute("difficulty")) {
+    gc_data->diff = a.value("difficulty").toString().toDouble() * 10;
+  }
+  if (a.hasAttribute("terrain")) {
+    gc_data->terr = a.value("terrain").toString().toDouble() * 10;
+  }
+
+  if (a.hasAttribute("cache_type")) {
+    QString t = a.value("cache_type").toString();
+    gc_data->type = nc_mktype(t);
+    if (t == "normal") {
+      wpt_tmp->icon_descr = "Geocache-regular";
+    } else if (t == "multi-part") {
+      wpt_tmp->icon_descr = "Geocache-multi";
+    } else if (t == "moving_travelling") {
+      wpt_tmp->icon_descr = "Geocache-moving";
+    } else {
+      wpt_tmp->icon_descr = QString("Geocache-%-%1").arg(t);
     }
-    waypt_add(wpt_tmp);
   }
 
-  xml_free_converted_attrs(attr);
-  xml_free_converted_string(el);
-}
+  if (a.hasAttribute("hidden_date")) {
+    QString h = a.value("hidden_date").toString();
+    QDateTime hd = QDateTime::fromString(h, "yyyy-MM-dd");
+    wpt_tmp->SetCreationTime(hd);
+  }
 
-static void
-nav_end(void* data, const XML_Char* el)
-{
-}
+  if (a.hasAttribute("retired")) {
+    if (a.value("terrain").toString() == "yes" && noretired) {
+      waypt_free(wpt_tmp);
+      return;
+    }
+  }
 
-static void
-nav_rd_init(const char* fname)
-{
-  fin = gbfopen(fname, "r", MYNAME);
+  if (a.hasAttribute("cache_size")) {
+    gc_data->container = nc_mkcont(a.value("cache_size").toString());
+  }
 
-  psr = XML_ParserCreate(NULL);
-  if (!psr) {
-    fatal(MYNAME ":Cannot create XML parser\n");
+  if (a.hasAttribute("description")) {
+    gc_data->desc_long.is_html = true;
+    gc_data->desc_long.utfstring = a.value("description").toString();
   }
 
-  XML_SetUnknownEncodingHandler(psr, cet_lib_expat_UnknownEncodingHandler, NULL);
-  XML_SetElementHandler(psr, nav_start, nav_end);
+  if (a.hasAttribute("comments")) {
+    gc_data->desc_short.is_html = true;
+    gc_data->desc_short.utfstring = a.value("comments").toString();
+  }
+
+
+  waypt_add(wpt_tmp);
 }
 
 static void
 nav_read(void)
 {
-  int len;
-  char buf[MY_CBUF];
-
-  while ((len = gbfread(buf, 1, sizeof(buf), fin))) {
-    if (!XML_Parse(psr, buf, len, gbfeof(fin))) {
-      fatal(MYNAME ":Parse error at %d: %s\n",
-            (int) XML_GetCurrentLineNumber(psr),
-            XML_ErrorString(XML_GetErrorCode(psr)));
+  QXmlStreamReader reader;
+  gpsbabel::File file(read_fname);
+  file.open(QIODevice::ReadOnly);
+  reader.setDevice(&file);
+
+  while (!reader.atEnd()) {
+    if (reader.name() == "CacheDetails" && 
+        reader.tokenType() == QXmlStreamReader::StartElement) { 
+      NaviReadCache(reader);
     }
+    reader.readNextStartElement();
   }
-
-  XML_ParserFree(psr);
 }
 
-#endif
-
 static void
 nav_rd_deinit(void)
 {
-  gbfclose(fin);
 }
 
 static void
 nav_wr_init(const char* fname)
 {
   fatal(MYNAME ": Does not support writing Navicache files.\n");
-  fout = gbfopen(fname, "w", MYNAME);
 }
 
 static void
 nav_wr_deinit(void)
 {
-  gbfclose(fout);
 }
 
 static void